﻿using System;
using System.Diagnostics;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using Microsoft.VisualBasic.CompilerServices;

namespace FMS.Formulation.Licensing.Engine
{


    internal class CryptoUtility
    {
        private static readonly byte[] _defaultInitializationVector = new byte[16]
        {
        9, 34, 210, 122, 46, 8, 214, 77, 98, 22,
        244, 187, 29, 46, 153, 154
        };

        private static bool _useFips = false;
        private static bool _useSha256 = false;
        private static bool _cryptoInitialized = false;

        public static bool IsFipsMode
        {
            get
            {
                if (_cryptoInitialized)
                {
                    return _useFips;
                }
                try
                {
                    RijndaelManaged rijndaelManaged = new RijndaelManaged();
                    TraceLogger.Log("Successfully created RijndaelManaged object in UseFIPS", TraceLevel.Info);
                }
                catch (InvalidOperationException ex)
                {
                    ProjectData.SetProjectError(ex);
                    _useFips = true;
                    TraceLogger.Log("UseFIPS set to True after error ", ex, TraceLevel.Info);
                    try
                    {
                        SHA256CryptoServiceProvider sha256Provider = new SHA256CryptoServiceProvider();
                    }
                    catch (PlatformNotSupportedException platformEx)
                    {
                        TraceLogger.Log("UseSha256 set to True after error ", platformEx, TraceLevel.Info);
                        _useSha256 = true;
                        ProjectData.ClearProjectError();
                    }
                    ProjectData.ClearProjectError();
                }
                finally
                {
                    _cryptoInitialized = true;
                }
                return _useFips;
            }
        }

        internal static byte[] DecryptData(byte[] data, byte[] key, byte[] initializationVector = null)
        {
            if (IsFipsMode)
            {
                return DecryptDataFips(data, key, initializationVector);
            }
            RijndaelManaged rijndaelManaged = null;
            try
            {
                rijndaelManaged = new RijndaelManaged();
                return PerformDecryption(rijndaelManaged, data, key, initializationVector);
            }
            catch (Exception ex)
            {
                ProjectData.SetProjectError(ex);
                throw ex;
            }
            finally
            {
                rijndaelManaged?.Clear();
            }
        }

        [SecuritySafeCritical]
        internal static byte[] DecryptDataFips(byte[] data, byte[] key, byte[] initializationVector = null)
        {
            AesCryptoServiceProvider aesProvider = null;
            try
            {
                GetSerializationPermissionSet().Assert();
            }
            catch (Exception ex)
            {
                ProjectData.SetProjectError(ex);
                ProjectData.ClearProjectError();
            }
            try
            {
                aesProvider = new AesCryptoServiceProvider();
                return PerformDecryption(aesProvider, data, key, initializationVector);
            }
            catch (Exception ex)
            {
                ProjectData.SetProjectError(ex);
                throw ex;
            }
            finally
            {
                aesProvider?.Clear();
            }
        }

        // Other methods would be similarly refactored...

        private static PermissionSet GetSerializationPermissionSet()
        {
            PermissionSet permissionSet = new PermissionSet(PermissionState.None);
            permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
            return permissionSet;
        }

        // Note: This is just a placeholder. The full implementation would require refactoring all methods.
        private static byte[] PerformDecryption(SymmetricAlgorithm algorithm, byte[] data, byte[] key, byte[] initializationVector)
        {
            // Placeholder implementation
            throw new NotImplementedException("Full implementation needed");
        }

        // Trace logging helper (would need actual implementation)
        private static class TraceLogger
        {
            public static void Log(string message, TraceLevel level) { /* Implementation */ }
            public static void Log(string message, Exception ex, TraceLevel level) { /* Implementation */ }
        }
    }
}
